package com.hbnu.dao;

import com.hbnu.entity.ShareStat;
import com.hbnu.entity.UserFile;
import com.hbnu.tools.UserFileTool;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

public class ShareDao extends JDBC{
    //创建分享
    public boolean createShare(String uid, ShareStat shareStat, int time) {
        try(PreparedStatement preparedStatement=getPreparedStatement(
                "insert into shares(uid,fid,uuid,pwd,time,size,collect)\n" +
                        "values(?,?,?,?,date_add(now(), interval ? hour),?,?);"
        )){
            // 设置 PreparedStatement 参数
            preparedStatement.setString(1, uid);
            preparedStatement.setInt(2, shareStat.getFid());
            preparedStatement.setString(3, shareStat.getUuid());
            preparedStatement.setString(4, shareStat.getPwd());
            preparedStatement.setInt(5, time);
            preparedStatement.setLong(6, shareStat.getSize());
            preparedStatement.setString(7, shareStat.getText());
            return preparedStatement.executeUpdate() > 0;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //获得全部有效链接，分享链接
    public List<ShareStat> getShareList(String uid) {
        try (PreparedStatement preparedStatement = getPreparedStatement(
                "select sid,fid,uuid,pwd,time,size from shares where uid = ? and is_deleted = 0"
        )){
            preparedStatement.setString(1,uid);
            ResultSet resultSet = preparedStatement.executeQuery();
            List<ShareStat> shareStatList = new ArrayList<>();
            while (resultSet.next()) {
                ShareStat shareStat=new ShareStat(
                        resultSet.getInt(1),
                        resultSet.getInt(2),
                        resultSet.getString(3),
                        resultSet.getString(4),
                        resultSet.getTimestamp(5).toLocalDateTime(),
                        resultSet.getLong(6)
                );
                shareStatList.add(shareStat);
            }
            return shareStatList;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //取消分享
    public boolean shareClose(int id) {
        try(PreparedStatement preparedStatement=getPreparedStatement(
                "update shares set is_deleted = 1 where sid= ?;"
        )){
            preparedStatement.setInt(1,id);
            return preparedStatement.executeUpdate()>0;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //获得分享id
    public ShareStat getShareFid(String code, String pwd) {
        try(PreparedStatement preparedStatement=getPreparedStatement(
                "select uid,fid,size,collect from shares where uuid = ? and pwd= ? and now()<time and is_deleted = 0;"
        )){
            preparedStatement.setString(1,code);
            preparedStatement.setString(2,pwd);
            ResultSet resultSet = preparedStatement.executeQuery();
            if(resultSet.next())
                return new ShareStat(resultSet.getString(1),resultSet.getInt(2),resultSet.getLong(3),resultSet.getString(4));
            else
                throw new RuntimeException("数据库异常");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //获得分享文件、夹  || 通过fid进行查询，并保存到本地缓存
    public Map<Integer, UserFile> getShareF(String text) {
        String sql="select fid,pid,fname,file_id,is_file\n" +
                "from files_folders where fid in ("+text+");";
        try(Statement statement = getStatement()){
            ResultSet resultSet = statement.executeQuery(sql);
            return UserFileTool.initUserFileMap(resultSet);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        //call select_share(4);
    }

    //保存链接
    public Map<Integer,Integer> saveShare(String uid,int fid, Map<Integer, UserFile> tmpIdUserFileMap) {
        try(PreparedStatement preparedStatement = getPreparedStatement0(
                "insert into files_folders(user_id,pid,fname,created_time,file_id,is_file) \n" +
                        "values(?,?,?,now(),?,?);"
        )){
            connection.setAutoCommit(false);  // 开始事务管理
            Queue<Integer> userFileQueue=new LinkedList<>();
            Map<Integer,Integer> keyMap=new HashMap<>();
            userFileQueue.add(fid);
            int key=0;
            while (!userFileQueue.isEmpty()){
                UserFile userFile= tmpIdUserFileMap.get(userFileQueue.poll());
                int file_id=userFile.getFile_id();
                preparedStatement.setString(1,uid);
                int pid = userFile.getPid();
                if(keyMap.containsKey(pid)) pid=keyMap.get(pid);
                preparedStatement.setInt(2,pid);
                preparedStatement.setString(3,userFile.getFname());
                if (file_id==0) {
                    preparedStatement.setNull(4, java.sql.Types.INTEGER); // 设置为 NULL，使用 SQL INTEGER 类型
                } else {
                    preparedStatement.setInt(4, file_id); // 如果 file_id 不为 NULL，使用 setInt
                }
                preparedStatement.setInt(5,userFile.is_file()?1:0);
                //获取key
                if (preparedStatement.executeUpdate() > 0) {
                    // 获取生成的主键
                    try (ResultSet generatedKeys = preparedStatement.getGeneratedKeys()) {
                        if (generatedKeys.next()) {
                            // 获取生成的主键值（假设是 int 类型）
                            key= generatedKeys.getInt(1);
                        }
                    }
                }else throw new RuntimeException("数据库异常") ;
                //将子内容添加至队列
                if(userFile.hasChildren()){
                    userFileQueue.addAll(userFile.getList());
                }
                keyMap.put(userFile.getFid(),key);
                //便于缓存修改
                userFile.setFid(key);
                userFile.setPid(pid);
            }
            // 提交事务
            connection.commit();
            return keyMap;

        } catch (SQLException e) {
            try {
                connection.rollback();  // 如果有错误，回滚事务
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        }finally {
            try {
                //恢复自动提交
                connection.setAutoCommit(true);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
